#include "EventDispatcher.h"

#include <cstdio>
#include <cstdlib>

#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>

using std::perror;
using std::abort;

namespace Net{
    EventDispatcher::EventDispatcher()
    {
        m_nEventFd = kqueue();
        if( m_nEventFd < 0 )
        {
            perror("kqueue");
            abort();
        }
    }


    int EventDispatcher::RegisterForRead(int fd, IEventCallback *callback)
    {
        return RegisterEvent(fd, callback EVFILT_READ); 
    }

    int EventDispatcher::RegisterForWrite(int fd, 
        IEventCallback *callback)
    {
        return RegisterEvent(fd, callback,EVFILT_WRITE);
                 
    }

    int EventDispatcher::RegisterForReadWrite(int fd, 
        IEventCallback *callback)
    {
        return RegisterEvent(fd, callback, EVFILT_WRITE | EVFILT_READ);
    }

    int EventDispatcher::RegisterEvent(int fd, IEventCallback *callback, 
            int event)
    {
        EventHashSet::iterator iterFd = m_setFdToCallback.find(
                EventToCallback(fd, NULL, 0)
                );

        //如果已经存在这个事件，则先注销之前的回调处理
        if( iterFd != m_setFdToCallback.end() )
        {
            EventToCallback& etcb = iterFd->second;

            IEventCallback *pOther = etcb.pCallback;
            //需要执行回调
            if( pOther )
            {
                pOther->UnRegisteration();
            }

            //更新当前FD的事件
            ModFD(fd, event);

        }
        //没有这个事件则直接新增一个
        else
        {
            AddFD(fd, event);
            m_setFdToCallback.insert( 
                    EventToCallback(fd, callback, event) 
                    );
        }

        //当前fd对应的事件已经更新，调用OnRegistration回调、
        return callback->OnRegisteration();
    }

    int EventDispatcher::ModFD(int fd, int event)
    {
        struct kevent kv;
        kv.ident    = fd;
        kv.filter   = ; 
        //如果对应的fd事件已经存在,则EV_ADD会替换原有的事件
        kv.flags    = EV_ADD;           
        kv.fflags   = event;
        kv.data     = 0;
    }

    int EventDispatcher::AddFD(int fd, int event);
    int EventDispatcher::DelFD(int fd);


}
